//SPI通讯和控制与数据传输协议接口

#ifndef __SPI_H
#define __SPI_H

#include "stm32f4xx.h"
#include <stdio.h>
#include "includes.h"

#define USE_DMA_TRANS
/* 定义接收缓冲区和发送缓冲区的长度 */
#define RX_LEN (int)1024
#define TX_LEN (int)20

#define SPI_PREC_2 (uint8_t)0x01
#define SPI_PREC_4 (uint8_t)0x02
#define SPI_PREC_8 (uint8_t)0x03
#define SPI_PREC_16 (uint8_t)0x04
#define SPI_PREC_32 (uint8_t)0x05
#define SPI_PREC_64 (uint8_t)0x06
#define SPI_PREC_128 (uint8_t)0x07
#define SPI_PREC_256 (uint8_t)0x08
//系统类型(3BIT)
#define AD1_CARD (0ULL << 61)
#define AD2_CARD (1ULL << 61)
#define DA_CARD (2ULL << 61)
//主控制字（4BIT）
#define Demodulation_parameters (0ULL << 57) //解调参数
#define Decoding_parameters (3ULL << 57)     //译码参数
#define OUTPUT (3ULL << 57)                  //输出
//通道号备用(5BIT)
#define Channel_number_standby(opt) (((unsigned long long)opt & 0x1F) << 52) //传参，opt为通道号，取值范围为0～31
//子控制字(4BIT)
#define Carrier_frequency_control_word (0ULL << 48) //载波频率控制字
#define Symbol_rate_control_word (1ULL << 48)       //符号速率控制字
#define Modulation_system (2ULL << 48)              //调制方式
#define Spectrum_inversion (3ULL << 48)             //频谱倒置
#define Symbol_rate_value (4ULL << 48)              //符号速率值
#define Balance (6ULL << 48)                        //均衡
#define Decoding_mode (0ULL << 48)                  //译码方式
#define Decoding_rate (1ULL << 48)                  //译码码率
#define RS_Decoding_mode (2ULL << 48)               //RS译码模式
#define RS_Mixed_depth (3ULL << 48)                 //RS交织深度
#define Difference_options (4ULL << 48)             //差分选项
#define Scrambler_format (5ULL << 48)               //扰码格式
#define Scrambler_initial_state (6ULL << 48)        //扰码初态
#define Frame_structure (7ULL << 48)                //帧结构
#define Acquisition_mode (15ULL << 48)              //采集模式
//备用参数(16BIT)
#define Standby_parameter(opt) (((unsigned long long)opt & 0xFFFFULL) << 32) //传参，opt为备用参数数据，取值范围0-65535

#define KHZ(x) ((long long)(x * 1000.0 + .5))
#define MHZ(x) ((long long)(x * 1000000.0 + .5))
#define GHZ(x) ((long long)(x * 1000000000.0 + .5))
extern const double Fsysclk;

typedef struct Devicepara
{
    u32 carrierfrequency;      /* 保存当前的：载波频率,单位Hz */  
    u32 symbolrate;            /* 保存当前的：符号速率,单位Hz */
    u32 carrierfrequencycw;    /* 保存当前的：载波频率控制字值 */
    u32 symbolratecw;          /* 保存当前的：符号速率控制字值 */
    u32 modulationsystem;      /* 保存当前的：调制方式，BIT3_BIT0:0000表示BPSK, 0001表示QPSK, 0010表示OQPSK, 
                                0011表示8PSK,0100表示16QAM，0101表示8QAM */
    u32 spectruminversion;     /* 保存当前的：频谱倒置，BIT0：0表示不倒置（正谱），1表示倒置 */
    u32 symbolratevalue;       /* 保存当前的：符号速率值，BIT31_BIT0：信息频率值，单位为Hz */
    u32 balance;               /* 保存当前的：均衡，BIT0：0表示OFF，1表示ON */
    u32 decodingmode;          /* 保存当前的：译码方式，BIT3～BIT0： 0000：OFF； 0001：VITERBI; 
                                0010:TCP; 0011：TCM; 0100：LDPC;0101：SEQ. 其他备用 */
    u32 decodingrate;          /* 保存当前的：译码码率，BIT4～BIT0：00000:1/1; 00001:1/2;00010:2/3;00011:3/4; 
                                00100:5/6;00101:7/8; 00110:5/16; 00111:0.49;
                                01000:0.79;01001:0.95;01010:21/44;其他备用 */
    u32 RSdecodingmode;        /* 保存当前的：RS译码模式，BIT3_BIT0：0000表示OFF, 0001表示RS(126,112), 
                                0010表示RS(219,201), 0011表示RS(194,178), 
                                0100表示RS(204,188), 0101表示RS(255,223), 0110表示RS(160,146) */
    u32 RSmixeddepth;          /* 保存当前的：RS交织深度，BIT1_BIT0：0～3分别表示NONE/4/8/12 */
    u32 differenceoptions;     /* 保存当前的：差分选项，BIT0：0表示OFF，1表示ON */
    u32 scramblerformat;       /* 保存当前的：扰码格式，BIT3_BIT0:0000表示OFF（解扰关闭）, 
                                0001表示V35(IESS), 0010表示V35(CCITT), 
                                0011表示IBS15, 0100表示TCP11, 0101表示TCP12, 0110表示RS，0111表示V35(EF)。*/
    u32 scramblerinitialstate; /* 保存当前的：扰码初态,BIT14_BIT0(只在置位式填写暂用15比特,高位在前)
                                如:设扰码为IBS15时,初态xED10,BIT14_BIT0=1110110100010000; */
    u32 framestructure;        /* 保存当前的：帧结构,BIT2_BIT0：000表示CUSTOM,001表示IBS,010表示IDR, 011表示 EDMAC, 100表示 DVB, */
    u32 acquisitionmode;       /* 保存当前的：采集模式, BIT0：0表示解调，1表示译码 */
} Devicepara;

extern Devicepara *pDevicepara;
extern uint8_t SPI_RX_BUFFER[RX_LEN];
extern uint8_t SPI_TX_BUFFER[TX_LEN];
void Spi_Config(void);
unsigned long long SPI2_transfer64bit(unsigned long long data);
void NSS_enable(void);
void NSS_disable(void);
/* spi初始化 */
void bsp_spi_init(void);
/* 设置SPI的工作速度 */
void set_spi_speed(uint8_t speed_mode);

#ifdef USE_DMA_TRANS
void spi_trans(uint8_t *rx_buf,
			   uint8_t *tx_buf,
			   uint16_t length);

void spi_trans_read(uint8_t *rx_buf,
					uint8_t *tx_data,
					uint16_t length);

void spi_trans_write(uint8_t *rx_data,
					 uint8_t *tx_buffer,
					 uint16_t length);
#else
void spi_trans(uint8_t *rx_buf,
			   uint8_t *tx_buf,
			   uint16_t length);
#endif
//其中Fsysclk为混频器VCO锁定内部时钟，Fc为载波中心频率，单位为MHz
u32 get_Carrier_frequency_control_word(const double Fc);
double get_Carrierfreq_from_control_word(const u32 ftw);
//其中Fsysclk为混频器VCO锁定内部时钟,Fd为符号速率,单位为Mbps
u32 get_Symbol_rate_control_word(const double Fd);
void device_init(void);
void device_free(void);
void flash_write(void);
#endif /* __SPI_H */
